package ch.subgate.spritestudio.tools;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Environment;
import android.widget.Toast;

import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;

import ch.subgate.spritestudio.constants.Constants;
import ch.subgate.spritestudio.types.Sprite;

public class DataManager {
	
	/** Make sure all relevant directories do exist */
	public static boolean mkdirs() {
		boolean result = true;
		String storageState = Environment.getExternalStorageState();
		
		if (storageState.equals(Environment.MEDIA_MOUNTED)) {
			File dir;
			dir = new File(
					Environment.getExternalStorageDirectory()
					+ "/" + Constants.DEFAULT_MAIN_DIR
					+ "/" + Constants.DEFAULT_PROJECT_DIR
					+ "/" + Constants.DEFAULT_THUMBNAIL_DIR);
			result = result && dir.mkdirs();
			dir = new File(
					Environment.getExternalStorageDirectory()
					+ "/" + Constants.DEFAULT_MAIN_DIR
					+ "/" + Constants.DEFAULT_PALETTE_DIR);
			result = result && dir.mkdirs();
		}
		else {
			result = false;
		}
		
		return result;
	}
	
	/** Method to save a bitmap to a PNG file */
	public static boolean saveBitmapPNG(
			Context context,
			Bitmap bitmap,
			String projectName,
			String fileName) {
		//Get the external storage state
		String storageState = Environment.getExternalStorageState();
		
		//Prepare toast notification
		Toast msg;
		
		if (storageState.equals(Environment.MEDIA_MOUNTED)) {
			if (fileName.substring(fileName.length() - 4).toLowerCase().compareTo(".png") != 0) {
				//Set filename accordingly
				fileName += ".PNG";
			}
			
			//Get pictures folder
			String exDir = Environment.getExternalStorageDirectory().toString();
			
			//Create a file to the project directory
			File path;
			path = new File(
					exDir
					+ "/" +Constants.DEFAULT_MAIN_DIR
					+ "/" + projectName);
			
			//Make directories if necessary
			path.mkdirs();
			
			File file = new File(path, fileName);
			
			try {
				FileOutputStream out = new FileOutputStream(file);
				
				bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
				
				out.flush();
				out.close();
			}
			catch (Exception e) {
				msg = Toast.makeText(
						context,
						"Error: Unable to write bitmap data.",
						Toast.LENGTH_LONG);
				msg.show();
				return false;
			}
		}
		else {
			//External storage is not available or not writable
			msg = Toast.makeText(
					context,
					"Error: External storage not available.",
					Toast.LENGTH_LONG);
			msg.show();
			return false;
		}
		
		msg = Toast.makeText(
				context,
				"Successful: " + fileName + " saved.",
				Toast.LENGTH_LONG);
		msg.show();
		
		return true;
	}
	
	/** Saves a sprite to a png on sdcard */
	public static boolean saveSpritePNG(Context context, Sprite sprite) {
		if (sprite.getBitmap() != null && !sprite.getBitmap().isRecycled()) {
			saveBitmapPNG(
					context,
					sprite.getBitmap(),
					Constants.DEFAULT_PROJECT_DIR,
					sprite.mFileName);
			return true;
		}
		else {
			return false;
		}
	}
	
	/** Loads a single png bitmap from path */
	public static Bitmap loadBitmapFromPath(String path) {
		Bitmap bitmap = null;
		Bitmap result = null;
		
		//Load the picture file into an immutable bitmap
		bitmap = BitmapFactory.decodeFile(path);
		if (bitmap != null) {
			result = Bitmap.createBitmap(
					bitmap.getWidth(),
					bitmap.getHeight(),
					Bitmap.Config.ARGB_8888);
			int[] pixels = new int[bitmap.getWidth() * bitmap.getHeight()];
			bitmap.getPixels(pixels, 0, bitmap.getWidth(), 0, 0, bitmap.getWidth(), bitmap.getHeight());
			result.setPixels(pixels, 0, result.getWidth(), 0, 0, result.getWidth(), result.getHeight());
			
			//Recycle the immutable bitmap, as its no longer used
			bitmap.recycle();
			bitmap = null;
		}
		return result;
	}
	
	public static String makeSpritePathFromNames(String fileName, String projectName) {
		String extDir = Environment.getExternalStorageDirectory().getPath();
		
		if (fileName == null) {
			return null;
		}
		else {
			if (projectName == null) {
				return extDir 
						+ "/" + Constants.DEFAULT_MAIN_DIR
						+ "/" + Constants.DEFAULT_PROJECT_DIR
						+ "/" + fileName;
			}
			else {
				return extDir
						+ "/" + Constants.DEFAULT_MAIN_DIR
						+ "/" + projectName
						+ "/" + fileName;
			}
		}
	}
	
	/** Loads a single png bitmap with name reference */
	public static Bitmap loadBitmapFromNames(String fileName, String projectName) {
		String path = makeSpritePathFromNames(fileName, projectName);
		
		if (path == null) {
			return null;
		}
		else {
			return loadBitmapFromPath(path);
		}
	}
	
	/** Loads all sprites from a directory */
	public static void loadProjectSprites(
			ArrayList<Sprite> sprites,
			String projectName,
			boolean loadThumbnail) {
		File dir;
		
		if (projectName == null) {
			projectName = Constants.DEFAULT_PROJECT_DIR;
		}
		
		dir = new File(
				Environment.getExternalStorageDirectory().getPath()
				+ "/" + Constants.DEFAULT_MAIN_DIR
				+ "/" + projectName);
		
		if (dir != null) {
			if (dir.exists()) {
				File[] files = dir.listFiles();
				
				if (files != null) {
					Sprite sprite;
					Bitmap bitmap;
					for (File file : files) {
						if (file.isFile()) {
							bitmap = loadBitmapFromPath(file.getPath());
							if (bitmap != null) {
								sprite = new Sprite(
										file.getName(),
										projectName);
								if (loadThumbnail) {
									sprite.setBitmap(Bitmap.createScaledBitmap(bitmap, 32, 32, false), 1);
									bitmap.recycle();
								}
								else {
									sprite.setBitmap(bitmap, 1); // TODO load frame count from database
								}
								sprites.add(sprite);
							}
						}
					}
				}
			}
		}
	}
	
	public static void deleteSprite(Sprite sprite) {
		File file = new File(
				Environment.getExternalStorageDirectory().getPath()
				+ "/" + Constants.DEFAULT_MAIN_DIR
				+ "/" + sprite.mProjectName
				+ "/" + sprite.mFileName);
		if (file.exists()) {
			file.delete();
		}
		file = new File(
				Environment.getExternalStorageDirectory().getPath()
				+ "/" + Constants.DEFAULT_MAIN_DIR
				+ "/" + sprite.mProjectName
				+ "/" + Constants.DEFAULT_THUMBNAIL_DIR
				+ "/" + sprite.mFileName);
		if (file.exists()) {
			file.delete();
		}
		sprite.recycle();
	}
}
